"""
Author        yongfa
Date          2022-07-05 15:42:01
LastEditTime  2023-09-07 07:26:09
LastEditors   yongfa
Description   插件库
"""
import os

from flask_migrate import Migrate
from flask_redis import FlaskRedis
from flask_jwt_extended import JWTManager
from flask_caching import Cache
from flask_login import LoginManager
from casbin_sqlalchemy_adapter import Adapter
import casbin
from celery import Celery
from celeryconfig import CeleryConfig
from flask_limiter.util import get_remote_address
from flask_limiter import Limiter
from flask_cors import CORS
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration


from .sqlalchemy import db
migrate = Migrate()
redis_client = FlaskRedis()
jwt = JWTManager()
cache = Cache()
limiter = Limiter(key_func=get_remote_address)  # 限制
cors = CORS()


# celery
celery_app = Celery(__name__, broker=CeleryConfig.broker_url, backend=CeleryConfig.result_backend)
celery_app.config_from_object(CeleryConfig)


# casbin
# adapter = Adapter('sqlite:///rbac.db')
adapter = Adapter(os.getenv('SQLALCHEMY_DATABASE_URI', 'mysql+pymysql://root:root321@172.19.43.180:3306/restx'))
casbin_enforcer = casbin.Enforcer('rbac_model.conf', adapter)

login_manager = LoginManager()

def configure_extensions(app):
    """应用扩展库"""
    db.init_app(app)
    migrate.init_app(app, db)
    redis_client.init_app(app)
    jwt.init_app(app)
    cache.init_app(app)
    limiter.init_app(app)
    cors.init_app(app, supports_credentials=True)
    login_manager.init_app(app)

    make_celery(app)

    if os.getenv('APP_SETTINGS') in ['prod']:
        sentry_sdk.init(
            dsn=app.config['SENTRY_URL'],
            traces_sample_rate=1.0,
            integrations=[FlaskIntegration()]
        )


def make_celery(app):
    # celery_app.conf.update(app.config)
    TaskBase = celery_app.Task

    class ContextTask(TaskBase):
        abstract = True

        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)

        def on_success(self, retval, task_id, args, kwargs):
            print('celery task {} success'.format(task_id))

    celery_app.Task = ContextTask
    return celery_app
